
package com.insigma.business.qrcode.common._provider.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.cache.Cache;
import com.insigma.business.qrcode.common.converter.CareWelfareMerchantInfoProviderConverter;
import com.insigma.business.qrcode.common.converter.CommonFavoriteProviderConverter;
import com.insigma.business.qrcode.common.dto.CommonFavoriteBSearcher;
import com.insigma.business.qrcode.common.dto.CommonFavoriteDO;
import com.insigma.business.qrcode.common.dto.CommonFavoriteSearchRequest;
import com.insigma.business.qrcode.common.dto.CommonFavoriteUpdateRequest;
import com.insigma.business.qrcode.common._provider.BaseProviderImpl;
import com.insigma.business.qrcode.common._provider.CommonFavoriteProvider;
import com.insigma.business.qrcode.common.service.CommonFavoriteService;
import com.insigma.business.qrcode.common.template.BasePagingResponse;
import com.insigma.business.qrcode.common.template.MemCacheManager;
import com.insigma.business.qrcode.common.template.area.ScenarioCodeEnum;
import com.insigma.business.qrcode.common.template.area.ServiceCallback;
import com.insigma.business.qrcode.common.util.BizCheckUtil;
import com.insigma.business.qrcode.common.util.RedisUtils;
import com.insigma.business.qrcode.common.util.ResponseUtils;
import com.insigma.business.qrcode.common.util.SessionUtils;
import com.insigma.business.qrcode.common.vo.BaseDeleteRequest;
import com.insigma.business.qrcode.common.vo.BaseResponse;
import com.insigma.business.qrcode.intell.entity.CommonPolicyDO;
import com.insigma.business.qrcode.merchant.entity.CareWelfareMerchantInfoDO;
import com.insigma.business.qrcode.merchant.service.CareWelfareMerchantInfoService;
import com.insigma.business.qrcode.pay.dto.CommonFavoriteInsertRequest;
import com.insigma.business.qrcode.soldier.request.BaseGetRequest;
import com.insigma.business.qrcode.welfare.dto.CareWelfareMerchantInfoDTO;
import com.insigma.business.qrcode.welfare.dto.CommonFavoriteDTO;
import com.insigma.business.qrcode.welfare.dto.CommonFavoriteTypeEnum;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.concurrent.TimeUnit;


@Slf4j
@Service
@Component("commonFavoriteProvider")
public class CommonFavoriteProviderImpl extends BaseProviderImpl implements CommonFavoriteProvider {

    @Autowired
    private CommonFavoriteService commonFavoriteService;

    Cache<String, Object> cache = MemCacheManager.getInstance(5, TimeUnit.MINUTES);
    @Autowired
    private RedisUtils redisUtils;

    @Autowired
    private CareWelfareMerchantInfoService careWelfareMerchantInfoService;


    @Override
    public BasePagingResponse<List<CommonFavoriteDTO>> searchCommonFavorite(CommonFavoriteSearchRequest searchRequest) {
        final BasePagingResponse<List<CommonFavoriteDTO>> basePagingResponse = new BasePagingResponse<>();
        serviceTemplate.execute(basePagingResponse, new ServiceCallback() {
            @Override
            public void check() {
                BizCheckUtil.checkNotNull(searchRequest, "查询分页CommonFavorite的请求参数不能为空");
            }

            @Override
            public void executeService() {
                final CommonFavoriteBSearcher commonFavoriteBSearcher = CommonFavoriteProviderConverter.convertRequestSO2Searcher(searchRequest);
//                final List<CommonFavoriteDO> commonFavoriteDOList = commonFavoriteService.search(commonFavoriteBSearcher);
                PageHelper.startPage(searchRequest.getPageNo(), searchRequest.getPageSize());
                final List<CommonFavoriteDO> commonFavoriteDOList = commonFavoriteService.searchMerchant(commonFavoriteBSearcher);
                PageInfo<CommonFavoriteDO> pageInfo = new PageInfo<>(commonFavoriteDOList);

                final List<CommonFavoriteDTO> commonFavoriteDTOList = CommonFavoriteProviderConverter.convertResponseDOList2DTOList(commonFavoriteDOList);

                if (!CollectionUtils.isEmpty(commonFavoriteDTOList)) {
                    for (CommonFavoriteDTO commonFavoriteDTO : commonFavoriteDTOList) {
                        Integer integer = commonFavoriteService.countByTypeAndId(commonFavoriteDTO.getType(), commonFavoriteDTO.getBizId());
                        if ("MERCHANT".equals(commonFavoriteDTO.getType())) {
                            CareWelfareMerchantInfoDO careWelfareMerchantInfoDO = careWelfareMerchantInfoService.get(commonFavoriteDTO.getBizId());
                            commonFavoriteDTO.setCareWelfareMerchantInfoDTO(CareWelfareMerchantInfoProviderConverter.convertResponseDO2DTO(careWelfareMerchantInfoDO));
                        }
                        commonFavoriteDTO.setFavoriteNum(integer);
                    }
                }

                ResponseUtils.buildSuccessPagingResponse(basePagingResponse, commonFavoriteDTOList, searchRequest, pageInfo.getTotal());
            }

            @Override
            public ScenarioCodeEnum getScenarioEnum() {
                return ScenarioCodeEnum.COMMON_FAVORITE_SEARCH;
            }
        });

        return basePagingResponse;
    }

    @Override
    public BaseResponse<CommonFavoriteDTO> getCommonFavorite(BaseGetRequest baseGetRequest) {
        final BaseResponse<CommonFavoriteDTO> baseResponse = new BaseResponse<>();
        serviceTemplate.execute(baseResponse, new ServiceCallback() {
            @Override
            public void check() {
                BizCheckUtil.checkNotNull(baseGetRequest, "获取单条CommonFavorite的请求参数不能为空");
                BizCheckUtil.checkNotBlank((String) baseGetRequest.getId(), "id不能为空");
            }

            @Override
            public void executeService() {
                final CommonFavoriteDO commonFavoriteDO = commonFavoriteService.get((String) baseGetRequest.getId());
                final CommonFavoriteDTO remoteObj = CommonFavoriteProviderConverter.convertResponseDO2DTO(commonFavoriteDO);
                ResponseUtils.setupSuccessResponse(baseResponse, remoteObj);
            }

            @Override
            public ScenarioCodeEnum getScenarioEnum() {
                return ScenarioCodeEnum.COMMON_FAVORITE_GET;
            }
        });
        return baseResponse;
    }

    @Override
    public BaseResponse<String> insertCommonFavorite(CommonFavoriteInsertRequest insertRequest) {
        final BaseResponse<String> baseResponse = new BaseResponse<>();
        serviceTemplate.execute(transactionTemplate, baseResponse, new ServiceCallback() {
            @Override
            public void check() {
                BizCheckUtil.checkNotNull(insertRequest, "新增CommonFavorite的请求参数不能为空");
            }

            @Override
            public void executeService() {
                String soldierUserId = SessionUtils.getSoldierUserId();
                SessionUtils.buildCreatorOfSoldier(insertRequest);
                CareWelfareMerchantInfoDO dto = careWelfareMerchantInfoService.get(insertRequest.getBizId());
                BizCheckUtil.checkNotNull(dto, "不存在");
                insertRequest.setBizName(dto.getName());
                insertRequest.setType(CommonFavoriteTypeEnum.MERCHANT.name());
                insertRequest.setBizLogo(dto.getLogo());
                insertRequest.setSoldierId(soldierUserId);
                insertRequest.setBizImg(dto.getSurroundings());
                if (insertRequest.getFavorite() != null && insertRequest.getFavorite().equals(false)) {
                    CommonFavoriteDO bySoldierIdAndTypeAndBizId = commonFavoriteService.getBySoldierIdAndTypeAndBizId(insertRequest.getSoldierId(), insertRequest.getType(), insertRequest.getBizId());
                    if (bySoldierIdAndTypeAndBizId != null) {
                        commonFavoriteService.delete(bySoldierIdAndTypeAndBizId.getId(), insertRequest.getCreatorType(), insertRequest.getCreatorId());
                    }
                } else {
                    CommonFavoriteDO bySoldierIdAndTypeAndBizId = commonFavoriteService.getBySoldierIdAndTypeAndBizId(insertRequest.getSoldierId(), insertRequest.getType(), insertRequest.getBizId());
                    BizCheckUtil.checkIsNull(bySoldierIdAndTypeAndBizId, "已收藏");
                    final CommonFavoriteDO commonFavoriteDO = CommonFavoriteProviderConverter.convertRequestIO2DO(insertRequest);

                    invalidCache(commonFavoriteDO.getType(), commonFavoriteDO.getBizId(), commonFavoriteDO.getSoldierId());
                    commonFavoriteService.insert(commonFavoriteDO);
                }

                ResponseUtils.setupSuccessResponse(baseResponse, "");
            }

            @Override
            public ScenarioCodeEnum getScenarioEnum() {
                return ScenarioCodeEnum.COMMON_FAVORITE_INSERT;
            }
        });
        return baseResponse;
    }

    @Override
    public BaseResponse<Integer> updateCommonFavorite(CommonFavoriteUpdateRequest updateRequest) {
        final BaseResponse<Integer> baseResponse = new BaseResponse<>();
        serviceTemplate.execute(transactionTemplate, baseResponse, new ServiceCallback() {
            @Override
            public void check() {
                BizCheckUtil.checkNotNull(updateRequest, "修改CommonFavorite的请求参数不能为空");
                BizCheckUtil.checkNotBlank(updateRequest.getId(), "id不能为空");
                BizCheckUtil.checkNotBlank(updateRequest.getModifierId(), "操作人不能为空");
                BizCheckUtil.checkNotBlank(updateRequest.getModifierType(), "操作人类型不能为空");
            }

            @Override
            public void executeService() {
                CommonFavoriteDO commonFavoriteDO = CommonFavoriteProviderConverter.convertRequestUO2DO(updateRequest);
                Integer affectRowNum = commonFavoriteService.update(commonFavoriteDO);
                ResponseUtils.setupSuccessResponse(baseResponse, affectRowNum);
            }

            @Override
            public ScenarioCodeEnum getScenarioEnum() {
                return ScenarioCodeEnum.COMMON_FAVORITE_UPDATE;
            }
        });
        return baseResponse;
    }


    @Override
    public BaseResponse<Integer> deleteCommonFavorite(BaseDeleteRequest deleteRequest) {
        final BaseResponse<Integer> baseResponse = new BaseResponse<>();
        serviceTemplate.execute(transactionTemplate, baseResponse, new ServiceCallback() {
            @Override
            public void check() {
                BizCheckUtil.checkNotNull(deleteRequest, "逻辑删除CommonFavorite的请求参数不能为空");
                BizCheckUtil.checkNotBlank((String) deleteRequest.getId(), "id不能为空");
            }

            @Override
            public void executeService() {
                final Integer affectRowNum = commonFavoriteService.delete((String) deleteRequest.getId(), deleteRequest.getModifierType(), (String) deleteRequest.getModifierId());
                ResponseUtils.setupSuccessResponse(baseResponse, affectRowNum);
            }

            @Override
            public ScenarioCodeEnum getScenarioEnum() {
                return ScenarioCodeEnum.COMMON_FAVORITE_DELETE_LOGICALLY;
            }
        });
        return baseResponse;
    }

    @Override
    public Boolean cachedIsFavorite(String type, String bizId, String soldierId) {
        if (Strings.isBlank(soldierId) || Strings.isBlank(bizId) || Strings.isBlank(type)) {
            return false;
        }
        String key ="FAVORITE" + type + ":" + bizId + ":" + soldierId;

        Object ifPresent = redisUtils.get(key);
        if (ifPresent != null) {
            return "1".equals(ifPresent);
        }

        CommonFavoriteDO favoriteDO = commonFavoriteService.getBySoldierIdAndTypeAndBizId(soldierId, type, bizId);
        if (favoriteDO != null) {
            redisUtils.set(key, "1");
            return true;
        } else {
            redisUtils.set(key, "0");
            return false;
        }
    }

    @Override
    public BaseResponse<Boolean> cachedIsFavoriteP(String type, String bizId, String soldierId) {
        return ResponseUtils.buildSuccessResponse(cachedIsFavorite(type, bizId, soldierId));
    }

    public Boolean invalidCache(String type, String bizId, String soldierId) {
        String key ="FAVORITE" + type + ":" + bizId + ":" + soldierId;
        redisUtils.deleteKey(key);
        return true;
    }
}
